<?php

/**
 * Base Antidetect class with common methods and properties
 *
 * Anti Detect login information.
 *
 * PHP versions 5
 * CAKEPHP versions 2.x
 * 
 * Green CMS - Content Management System and Framework Powerfull by Cakephp
 * Copyright 2012, GREEN GLOBAL CO., LTD (toancauxanh.vn)
 * 
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
 * Copyright 2005-2011, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @author        Technology Lab No.I <tech1@toancauxanh.vn>
 * @link          
 * @package       Controller.Component.Auth
 * @since         Green v 1.0
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */
App::uses('CakeEventListener', 'Event');

abstract class BaseAntidetect implements CakeEventListener {

    /**
     * Settings for this object.
     *
     * - `count` The maximum number incorrect within an login period of time
     * - `time` period of time pending
     * - `adapter` the adapter will storage detection,
     *
     * @var array
     */
    public $settings = array(
        'activated' => true,
        'count' => null,
        'time' => null,
        'adapter' => null,
    );

    /**
     * A Component collection, used to get more components.
     *
     * @var ComponentCollection
     */
    protected $_Collection;

    /**
     * Last blocked input.
     *
     * @var boolean
     */
    protected $_blocked = false;

    /**
     * Constructor
     *
     * @param ComponentCollection $collection The Component collection used on this request.
     * @param array $settings Array of settings to use.
     */
    public function __construct(ComponentCollection $collection, $settings) {
        $this->_Collection = $collection;
        $this->settings = Set::merge($this->settings, $settings);
        $this->getEventManager()->attach($this);
    }

    /**
     * Get last blocked input.
     *
     * @param mixed $status, boolean if set blocked/nonblocked or null if get current blocked.
     * @return boolean true on is blocked, false on non block.
     */
    public function isBlocked() {
        return !empty($this->_blocked);
    }

    /**
     * Get or set detection is activated
     *
     * @param mixed $status, boolean if set activated/deactivated or null if get current status.
     * @return boolean true if status is activated , false on deactivated
     */
    public function activate($status = null) {
        if (is_null($status)) {
            return (!empty($this->settings['activated']));
        }
        return $this->settings['activated'] = $status;
    }

    /**
     * Garbage collection
     * 
     * Permanently remove all expired and deleted data
     *
     * @return void
     */
    public function gc() {
        
    }

    /**
     * Anti detect a user input.
     *
     * @param Model $User user model
     * @param string $input to be authentication information from.
     * @return boolean true on is secure, false on failure.
     */
    abstract public function antidetect(Model $User, $input);

    /**
     * Stored a user input incorrect
     *
     * @param Model $User user model
     * @param string $input to be authentication information from.
     * @return void
     */
    abstract public function add(Model $User, $input);

    /**
     * Remove a user input incorrect has stored
     *
     * @param Model $User user model
     * @param string $input to be authentication information from.
     * @return void
     */
    abstract public function remove(Model $User, $input);

    /**
     * Returns the CakeEventManager manager instance that is handling any callbacks
     *
     * @return CakeEventManager
     */
    public function getEventManager() {
        return $this->_Collection->getEventManager();
    }

    /**
     * Returns a list of all events that will fire in the controller during it's lifecycle.
     * You can override this function to add you own listener callbacks
     *
     * @return array
     */
    public function implementedEvents() {
        return array(
            'Component.Authenticate.before' => 'antidetect',
            'Component.Authenticate.error' => 'add'
        );
    }

}
